package com.webdrop.gui;


import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONException;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.storage.client.Storage;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.webdrop.client.HttpRequest;
import com.webdrop.client.UrlToServer;


public class ViewFilesTab extends Composite{

	String googleId;
	String sessionId;
	Storage sessionStorage;
	VerticalPanel list;
	HorizontalPanel buttonList;
	CheckBox checkBox;
	String filePath;
	List<String> nameOfChecked;
	Button deleteButton = new Button("Delete files");
	Button downloadButton = new Button("Download files");
	ReadFiles readFiles;
	JSONNumber jsTotfileSize;
	UrlToServer url;
	
	/**
	 * Creates the tab where the list of all the file is shown
	 * @param readFiles the struct for the readfiles used to access the grid where the thumbs are displayed
	 */
	public ViewFilesTab(ReadFiles readFiles){
		this.readFiles = readFiles;
		list = new VerticalPanel();
		buttonList = new HorizontalPanel();
		url = new UrlToServer();
		buttonList.add(deleteButton);
		buttonList.add(downloadButton);
		downloadButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				if(!nameOfChecked.isEmpty()){
					for(int i = 0; i<nameOfChecked.size(); i++){

						Window.Location.assign(url.getUrlToServer()+"download.php?googleId="+googleId+"&sessionId="+sessionId+"&fileToDownload="+nameOfChecked.get(i));
					}
				}
			}
		});

		deleteButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				removeFile();
			}
		});
		initWidget(list);
	}


	/**
	 * Clears the list and sets the sessionstorage when loaded
	 */
	protected void onLoad(){
		super.onLoad();
		list.clear();

		list.add(buttonList);
		sessionStorage = Storage.getSessionStorageIfSupported();

		if(sessionStorage!=null){

			googleId = sessionStorage.getItem("googleId");
			sessionId=sessionStorage.getItem("sessionId");
			getFiles();
		}

	}

	/**
	 * Get the name of all the files that has been uploaded as a Json
	 */
	protected void getFiles()
	{

		new HttpRequest(url.getUrlToServer()+"getFilesJson.php?googleId="+googleId+"&sessionId="+sessionId) {
			@Override
			public void onResponseReceived(Request request, Response response) {
				if (200 == response.getStatusCode())
				{			
					try {
						JSONValue jsonValue = JSONParser.parseStrict(response.getText());
						JSONArray jsonArray = jsonValue.isArray();
						if (jsonArray != null) {
							generateTable(jsonArray);
						}
					} catch (JSONException  e) {

						displayError("Could not parse JSON");
					}
				}				
				else{
					displayError("Couldn't retrieve JSON (" + response.getStatusText() + ")");
				}

			}
		};
	}

	/**
	 * Generates the table with all the files and information about the files
	 * @param array contains all the and the information about the files as JSON
	 */
	protected void generateTable(JSONArray array)
	{		
		JSONValue jsonValue;
		nameOfChecked = new ArrayList<String>();
		for (int i=0; i<array.size(); i++) {
			JSONObject json;
			JSONString jsfileName, jsfileType, jsfileModified;
			JSONNumber jsfileSize;

			if ((json = array.get(i).isObject()) == null) continue;

			if(i == array.size()-1){
				if ((jsonValue = json.get("totFileSize")) == null) continue;
				if ((jsTotfileSize = jsonValue.isNumber()) == null) continue;
			}

			if ((jsonValue = json.get("fileName")) == null) continue;
			if ((jsfileName = jsonValue.isString()) == null) continue;

			if ((jsonValue = json.get("fileType")) == null) continue;
			if ((jsfileType = jsonValue.isString()) == null) continue;

			if ((jsonValue = json.get("fileSize")) == null) continue;
			if ((jsfileSize = jsonValue.isNumber()) == null) continue;

			if ((jsonValue = json.get("fileModified")) == null) continue;
			if ((jsfileModified = jsonValue.isString()) == null) continue;


			//remove "
			final String filePath = jsfileName.toString().replaceAll("\"", "");
			final String fileName;

			HorizontalPanel box = new HorizontalPanel();
			box.addStyleName("box");

			HorizontalPanel boxLink = new HorizontalPanel();
			boxLink.addStyleName("boxLink");

			HorizontalPanel boxFileSize = new HorizontalPanel();

			HorizontalPanel boxFileType = new HorizontalPanel();
			HorizontalPanel boxFileModified = new HorizontalPanel();

			fileName = filePath.substring(filePath.lastIndexOf("/")+1, filePath.length());

			final Label nameLink = new Label(fileName);
			nameLink.addStyleName("link");
			nameLink.addMouseOverHandler(new MouseOverHandler() {
				@Override
				public void onMouseOver(MouseOverEvent event) {
					nameLink.setStyleName("link-over");

				}
			});
			nameLink.addMouseOutHandler(new MouseOutHandler() {
				@Override
				public void onMouseOut(MouseOutEvent event) {
					nameLink.setStyleName("link");

				}
			});
			
			nameLink.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					new HttpRequest(url.getUrlToServer()+"getGalleryImage.php?googleId="+googleId+"&sessionId="+sessionId+"&imageName="+fileName) {
						@Override
						public void onResponseReceived(Request request, Response response) {
							if (200 == response.getStatusCode())
							{			
								try {
									String result = response.getText();
									//									if(!result.isEmpty())
									Window.open(result, "_blank", "height=640px," + "width=800px" );
								}
								catch (JSONException  e) {
									displayError("Could not create Image");
								}
							}
						}
					};					
				}
			});


			checkBox = new CheckBox();
			checkBox.addStyleName("checkBox");
			boxLink.add(checkBox);
			Label name = new Label("Name: ");
			name.addStyleName("labelName");
			boxLink.add(name);
			boxLink.add(nameLink);

			Label fileSize = new Label("Size: "+jsfileSize.toString()+" KByte" );
			fileSize.addStyleName("fileSize");
			boxFileSize.add( fileSize );

			Label fileType = new Label("Filetype: ."+jsfileType.toString().replaceAll("\"", "") );
			fileType.addStyleName("fileType");
			boxFileType.add( fileType );

			Label fileModified = new Label("Modified: "+jsfileModified.toString().replaceAll("\"", "") );
			fileModified.addStyleName("fileModified");
			boxFileModified.add( fileModified );

			checkBox.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {

					checkBox.setName(fileName);
					if(nameOfChecked.contains(fileName)){
						nameOfChecked.remove(fileName);
					}
					else{

						storeChecked(checkBox.getName());
					}
				}
			});

			box.add(boxLink);
			box.add(boxFileSize);
			box.add(boxFileType);
			box.add(boxFileModified);
			list.add(box);
		}
	}

	/**
	 * Displays an popup with an error message
	 * @param error the error message
	 */
	public void displayError(String error)
	{
		PopupPanel popUp = new PopupPanel();
		popUp.show();
		Label errorMLabel = new Label(error);
		popUp.setPopupPosition(500,100);

		popUp.setHeight("100px");
		popUp.setAutoHideEnabled(true);
		popUp.add(errorMLabel);
	}

	/**
	 * Stores the name of the checked files
	 * @param name the name of the file that has been marked in the checkbox
	 */
	public void storeChecked(String name){
		nameOfChecked.add(name);
	}

	/**
	 * Sends a request to the server to remove the files that has been checked in the checkboxes
	 */
	public void removeFile()
	{

		if(!nameOfChecked.isEmpty()){
			for(int i = 0; i<nameOfChecked.size(); i++){
				new HttpRequest(url.getUrlToServer()+"removeFile.php?googleId="+googleId+"&sessionId="+sessionId+"&fileToRemove="+nameOfChecked.get(i)) {
					@Override
					public void onResponseReceived(Request request, Response response) {
					}
				};
				if(i == nameOfChecked.size()-1){
					nameOfChecked.clear();				
					onLoad();
					readFiles.reloadGrid();
					readFiles.allFileName.clear();
				}
			}
		}
		else{
			Window.alert("You have not marked any files");
		}

	}
	/**
	 * Clears the list when unload
	 */
	protected void onUnload() 
	{
		super.onUnload();
		list.clear();
	}
}
